package api

import (
	"fmt"
	"gitee.com/coding_niann/gApi/log"
	"net/http"
	"strconv"
)

const (
	// MiddlewareBefore 在请求处理之前执行的中间件
	MiddlewareBefore = "middleware-before"
	// MiddlewareAfter 在请求处理之后的中间件
	MiddlewareAfter = "middleware-after"
)

var (
	middlewareBefore int // 中间件个数
	middlewareAfter  int // 中间件个数
	App              = New()
)

type routeGroup struct {
	prefix string
	router *router
}

type Engine struct {
	router *router
}

func newRouterGroup(prefix string, r *router) *routeGroup {
	return &routeGroup{prefix: prefix, router: r}
}

func (e *Engine) Group(prefix string) *routeGroup {
	return newRouterGroup(prefix, e.router)
}
func (r *routeGroup) UseAfter(path string, handler middlewareFunc) *routeGroup {
	middlewareAfter++
	r.router.addMiddleware(MiddlewareAfter+"-"+strconv.Itoa(middlewareAfter), r.prefix+path, handler)
	return r
}
func (r *routeGroup) UseBefore(path string, handler middlewareFunc) *routeGroup {
	middlewareBefore++
	r.router.addMiddleware(MiddlewareBefore+"-"+strconv.Itoa(middlewareBefore), r.prefix+path, handler)
	return r
}

func (r *routeGroup) GET(path string, handler HandlerFunc) {

	r.router.addRoute("GET", r.prefix+path, handler)
}

func (r *routeGroup) POST(path string, handler HandlerFunc) {
	r.router.addRoute("POST", r.prefix+path, handler)
}

type HandlerFunc func(c *Context)
type middlewareFunc func(c *Context) bool

func New() *Engine {
	return &Engine{router: newRouter()}
}

func (e *Engine) addRoute(method string, path string, handler HandlerFunc) {
	e.router.addRoute(method, path, handler)
}
func (e *Engine) addMiddleware(method string, path string, handler middlewareFunc) {
	e.router.addMiddleware(method, path, handler)
}
func (e *Engine) GET(path string, handler HandlerFunc) {
	e.addRoute("GET", path, handler)
}
func (e *Engine) UseBefore(path string, handler middlewareFunc) *Engine {
	middlewareBefore++
	e.addMiddleware(MiddlewareBefore+"-"+strconv.Itoa(middlewareBefore), path, handler)
	return e
}
func (e *Engine) UseAfter(path string, handler middlewareFunc) *Engine {
	middlewareAfter++
	e.addMiddleware(MiddlewareAfter+"-"+strconv.Itoa(middlewareAfter), path, handler)
	return e
}
func (e *Engine) POST(path string, handler HandlerFunc) {
	e.addRoute("POST", path, handler)
}

// ErrorHandler /**
func (e *Engine) ErrorHandler(fn func(c *Context, err error)) {
	e.router.errorHandler = fn
}
func (e *Engine) Start(addr string) {
	// icon
	addr = ":" + addr
	logger.LogBlue(" _       __     __    ____  ____  _ \n| |     / /__  / /_  / __ \\/ __ \\(_)\n| | /| / / _ \\/ __ \\/ / / / / / / / \n| |/ |/ /  __/ /_/ / /_/ / /_/ / /  \n|__/|__/\\___/_.___/_____/\\____/_/   \n")
	logger.LogGreen(fmt.Sprintf("Server Starting... Address:%s", addr))
	kv := e.router.handlers
	logger.LogGreen("Router:")
	for k, _ := range kv {
		logger.LogGreen(fmt.Sprintf("%s", k))
	}
	err := http.ListenAndServe(addr, e)
	if err != nil {
		panic(err)
	}
}
func (e *Engine) ServeHTTP(w http.ResponseWriter, req *http.Request) {
	c := newContext(w, req)
	e.router.handle(c)
}

func (e *Engine) Cors() {
	e.UseBefore("/**", func(c *Context) bool {
		c.SetHeader("Access-Control-Allow-Origin", "*")
		c.SetHeader("Access-Control-Allow-Methods", "GET,POST,PUT,DELETE,OPTIONS")
		c.SetHeader("Access-Control-Allow-Headers", "Content-Type,Access-Control-Allow-Headers,Authorization,X-Requested-With")
		c.SetHeader("Access-Control-Allow-Credentials", "true")
		if c.Method == "OPTIONS" {
			return false
		}
		return true
	})
	e.UseBefore("/", func(c *Context) bool {
		c.SetHeader("Access-Control-Allow-Origin", "*")
		c.SetHeader("Access-Control-Allow-Methods", "GET,POST,PUT,DELETE,OPTIONS")
		c.SetHeader("Access-Control-Allow-Headers", "Content-Type,Access-Control-Allow-Headers,Authorization,X-Requested-With")
		c.SetHeader("Access-Control-Allow-Credentials", "true")
		if c.Method == "OPTIONS" {
			return false
		}
		return true
	})

}
